


#ifndef __QE_QUEUE_H__
#define __QE_QUEUE_H__



#include "qe_def.h"
#include "qe_time.h"



/**
 * Min Priority Queue
 */
#define QE_MINPQ_F_CDC	0x0001
#define QE_MINPQ_F_RES	0x0002
typedef struct {
	void *data;
	unsigned int *prio;
	unsigned int elem_size;
	unsigned int num_elems;
	unsigned int cnt_elems;
	unsigned int flags;
	qe_bool    (*comparator)(void *, void *);
} qe_minpq;

typedef qe_minpq qe_workq;

typedef struct qe_workqueue_worker {
	void *data;
	qe_pts call_ts;
	qe_ret (*handle)(qe_workq *q, struct qe_workqueue_worker *w);
} qe_wq_worker;

/* Queue */
#define QE_QUEUE_RING		0x00000001U		/* Ring queue */
#define QE_QUEUE_CREATE		0x00000100U		/* Queue is create use qe_queue_new() */
typedef struct {
	void *data;
	unsigned int head;
	unsigned int tail;
	unsigned int count;
	unsigned int elem_size;
	unsigned int num_elems;
	unsigned int dynamic;
} qe_queue;

/* RingQueue */
typedef struct {
    void *buf;
	unsigned int head;
	unsigned int tail;
	unsigned int count;
	unsigned int depth;
	unsigned int elem_size;
	unsigned int num_elems;
} qe_ringq;

#define qe_ringq_buf_pos(ring)	((ring)->buf)



void qe_ringq_init(qe_ringq *q, void *buf, qe_size elem_size, qe_size num_elems);
void qe_ringq_fromarray(qe_ringq *q, void *array, qe_size elem_size, qe_size num_elems);
qe_ret qe_ringq_get(qe_ringq *q, int index, void *data);
qe_ret qe_ringq_enq(qe_ringq *q, void *data, unsigned int num);
qe_ret qe_ringq_deq(qe_ringq *q, void *data, unsigned int num);
qe_bool qe_ringq_isempty(qe_ringq *q);
qe_bool qe_ringq_isfull(qe_ringq *q);
qe_uint qe_ringq_wait(qe_ringq *q);
qe_uint qe_ringq_size(qe_ringq *q);
qe_uint qe_ringq_free(qe_ringq *q);
qe_uint qe_ringq_nbytes(qe_ringq *q);
qe_ringq *qe_ringq_create(qe_size elem_size, qe_size num_elems);
#define qe_ringq_new(type, num)		qe_ringq_create(sizeof(type), num)
void qe_ringq_clear(qe_ringq *q);

qe_bool qe_minpq_isfull(qe_minpq *q);
qe_bool qe_minpq_isempty(qe_minpq *q);
unsigned int qe_minpq_wait(qe_minpq *q);
qe_minpq *qe_minpq_create(unsigned int elem_size, unsigned int num_elems, 
	qe_bool (*comparator)(void *, void *));
qe_ret qe_minpq_peek(qe_minpq *q, void *u, unsigned int *p, int index);
qe_ret qe_minpq_del(qe_minpq *q, void *u, unsigned int *p, int index);
qe_ret qe_minpq_insert(qe_minpq *q, void *u, int p);
qe_ret qe_minpq_resize(qe_minpq *q, unsigned int capcaity);
qe_ret qe_minpq_delmin(qe_minpq *q, void *e, unsigned int *p);
#define qe_minpq_new(type, num, cmp)	qe_minpq_create(sizeof(type), num, cmp)

qe_queue *qe_queue_create(unsigned int elem_size, unsigned int num_elems);
qe_ret qe_queue_init(qe_queue *q, void *data, unsigned int elem_size, 
	unsigned int num_elems, unsigned int count);
qe_bool qe_queue_isempty(qe_queue *q);
qe_bool qe_queue_isfull(qe_queue *q);
unsigned int qe_queue_wait(qe_queue *q);
qe_ret qe_queue_peek(qe_queue *q, int index, void *elem);
qe_ret qe_queue_peek_elems(qe_queue *q, int index, void *elem, unsigned int num);
qe_ret qe_queue_enq(qe_queue *q, void *elem);
qe_ret qe_queue_enq_elems(qe_queue *q, void *elem, unsigned int num);
qe_ret qe_queue_deq(qe_queue *q, void *elem);
qe_ret qe_queue_deq_elems(qe_queue *q, void *elem, unsigned int num);
#define qe_queue_new(type, num)	qe_queue_create(sizeof(type), num)

qe_workq *qe_workqueue_new(unsigned int size);
qe_ret qe_workqueue_schedule(qe_workq *q, 
	qe_ret (*handle)(qe_workq * , qe_wq_worker *), qe_u32 ts,
		void *data);
qe_u64 qe_workqueue_service(qe_workq *q, qe_u32 ts);

#endif /* __QE_QUEUE_H__ */